package top.sxlai.service.impl;

import top.sxlai.constant.OtherStatus;
import top.sxlai.entity.DTO.OpFolderDTO;
import top.sxlai.entity.OpFolder;
import top.sxlai.entity.OpUser;
import top.sxlai.interceptor.LoginInterceptor;
import top.sxlai.mapper.OpUserMapper;
import top.sxlai.service.IFolderService;
import top.sxlai.util.CurrentSystemTime;
import top.sxlai.util.JwtUtil;
import top.sxlai.util.hbase.HbaseDML;
import top.sxlai.util.hbase.ParameterInitializer;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : sxl
 * @date : 2024/4/11 12:05
 * @Version: 1.0
 */
@Service
public class FolderServiceImpl implements IFolderService {
    private static final Logger log = LoggerFactory.getLogger(FolderServiceImpl.class);
    @Autowired
    private OpUserMapper opUserMapper;
    @Autowired
    private FileSystem fileSystem;
    @Value("${hbaseData.namespace}")
    private String namespace;
    @Value("${hbaseData.tables.folderTableName.tableName}")
    String tableName ;
    @Value("${hbaseData.tables.folderTableName.columnFamily}")
    String columnFamily;
    /**
     * 创建文件夹
     * @param folderDTO 数据
     * @return ResponseEntity
     * @throws Exception 异常
     */
    @Override
    public ResponseEntity<Map<String, String>> createFolder(OpFolderDTO folderDTO) throws Exception {
        System.setProperty("HADOOP_USER_NAME","root");
        Map<String, String> response = new HashMap<>();
        // 创建文件夹逻辑
        // 设置 Hadoop 用户名
        //获取用户userId
        String userId = JwtUtil.parseJWT(LoginInterceptor.getToken()).getSubject();
        //查询当前的文件夹信息
        List<String> columNames = new ArrayList<>();
        columNames.add("folderName");
        columNames.add("folderId");
        columNames.add("userId");
        OpFolder isFolder = null;
        try {
            isFolder = HbaseDML.getFolderCells(namespace, tableName,folderDTO.getHdfsPath(), columnFamily, columNames);
        } catch (IOException e) {
            log.info("查询内容为null,时间:{}", CurrentSystemTime.getTime());
        }
        //判定路径是否是初始的文件夹路径
        int pathLength = isFolderFirst(folderDTO.getHdfsPath());
        //获取用户的账号信息
        OpUser userInfo = opUserMapper.getUserInfo(userId);
        //判定是否已经创建了对应用户的初始文件夹
        if (pathLength==1) {
            assert isFolder != null;
            if (isFolder.getFolderName() == null && isFolder.getFolderId() == null && isFolder.getUserId() == null) {
                log.info("开始创建初始文件夹,时间:{}", CurrentSystemTime.getTime());
                //都是空的话则创建
                //hdfs路径,初始为用户的账号名称
                String hdfsPath = userInfo.getUsername();
                //创建文件夹路径
                Path path = new Path(hdfsPath);
                boolean success = fileSystem.mkdirs(path);
                if (success) {
                    //封装数据
                    Map<String ,String> colunmMap = new HashMap<>();
                    //最初始的文件夹Id设置为1
                    colunmMap.put("folderId", "1");
                    //初始文件夹名称是用户名
                    colunmMap.put("folderName", userInfo.getUsername());
                    //父级设置为0
                    colunmMap.put("parentId", "0");
                    colunmMap.put("hdfsPath", hdfsPath);
                    colunmMap.put("owner", userInfo.getUsername());
                    colunmMap.put("userId", userId);
                    colunmMap.put("createTime", CurrentSystemTime.getTime());
                    colunmMap.put("status", "1");
                    //给hbase添加最初的数据
                    boolean flag = HbaseDML.putCell(namespace, tableName, folderDTO.getHdfsPath(), columnFamily, colunmMap);
                    if (flag) {
                        //在初始文件夹上创建新的文件夹
                        //将创建好的初始文件夹路径封装到folderDTO
                        return createNewFolder(folderDTO, userInfo);
                    }
                }
            }else{
                //如果已经存在了，则直接创建新的文件夹
                return createNewFolder(folderDTO, userInfo);
            }
        } else {
                //folderId不等于1的时候之间创建
            return createNewFolder(folderDTO, userInfo);
        }
        response.put("message", OtherStatus.CREATEFOLDERFAILURE.getMessage());
        log.info("创建文件夹失败,时间:{}", CurrentSystemTime.getTime());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
    /**
     * 创建文件夹
     * @param folderDTO 数据
     * @param userInfo 用户信息
     * @return ResponseEntity
     * @throws IOException 异常
     */
    private ResponseEntity<Map<String, String>> createNewFolder(OpFolderDTO folderDTO, OpUser userInfo) throws IOException {
        Map<String, String> response = new HashMap<>();
        log.info("开始创建文件夹,时间:{}", CurrentSystemTime.getTime());
        //开始封装新建文件夹的信息
        //获取前面的
        String firstPath = folderDTO.getHdfsPath();
        //拼接新的hdfs路径
        String hdfsPath = firstPath + "/" + folderDTO.getFolderName() ;
        //创建文件夹
        Path path = new Path(hdfsPath);
        try {
            boolean success = fileSystem.mkdirs(path);
            if (success) {
                //封装数据
                Map<String,String> colunmMap = new HashMap<>();
                //文件id+1
                colunmMap.put("folderId",String.valueOf(folderDTO.getFolderId() + 1) );
                colunmMap.put("folderName", folderDTO.getFolderName());
                //父级设置为0
                colunmMap.put("parentId", "0");
                colunmMap.put("hdfsPath", hdfsPath);
                colunmMap.put("owner", userInfo.getNickname());
                colunmMap.put("userId",String.valueOf( userInfo.getUserid()) );
                colunmMap.put("createTime", CurrentSystemTime.getTime());
                colunmMap.put("status", "1");
                //给hbase添加最初的数据
                boolean createFolderFlag = HbaseDML.putCell(namespace, tableName, hdfsPath, columnFamily, colunmMap);
                if (createFolderFlag) {
                    response.put("message", OtherStatus.CREATEFOLDERSUCCESS.getMessage());
                    log.info("成功创建文件夹,时间:{}",CurrentSystemTime.getTime());
                    return ResponseEntity.ok(response);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        response.put("message", OtherStatus.CREATEFOLDERFAILURE.getMessage());
        log.info("创建文件夹失败,时间:{}",CurrentSystemTime.getTime());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }

    /**
     * 查询文件夹
     * @param folderDTO 数据
     * @return ResponseEntity
     * @throws IOException 异常
     */
    @Override
    public ResponseEntity<List<OpFolder>> queryFolder(OpFolderDTO folderDTO) throws IOException {
        //文件夹查询
        Map<String,String> response = new HashMap<>();
        log.info("开始查询文件夹,时间:{}", CurrentSystemTime.getTime());
        List<OpFolder> opFolders;
            opFolders = HbaseDML.filterScan(namespace, tableName,folderDTO.getHdfsPath(), columnFamily,
                    ParameterInitializer.getFolderColumns(), folderDTO.getSelectQueryWay(), "folder");
        List<OpFolder> filteredOpFolders = opFolders.stream()
                .filter(opFolder -> opFolder != null && !opFolder.getFolderName().isEmpty())
                .collect(Collectors.toList());
        return ResponseEntity.ok(filteredOpFolders);
    }

    //判断路径
    private int isFolderFirst(String fileFoldPath) {
        String [] folder = fileFoldPath.split("/");
        return folder.length;
    }
}